<?php
/**
 * Created by PhpStorm.
 * User: jack Wang
 * Date: 2021/10/11
 * Time: 10:45
 */

class User extends Base_Controller
{
    public function __construct()
    {
        parent::__construct();
        $this->load->model('users_model');
        $this->load->helper('common_helper');
        $this->load->service('User_service');
        $this->load->service('Activity_service');
        //加载CI表单验证库
        $this->load->library('form_validation');
    }

    /*
     * 获取个人信息
     */
    public function getUserInfo()
    {
        $data = $this->input->post();
        if (empty($data['id'])) {
            fail(400, '获取失败!');
        }
        $res = $this->users_model->findByid($data['id']);
        return $res ? success($res) : fail(400, '信息查询失败!');
    }

    /*
     * 用户账户信息修改
     */
    public function alertUserInfo()
    {
        $rules = [
            [
                'field' => 'id',
                'label' => '用户id',
                'rules' => 'required|numeric',
                'errors' => [
                    'required' => '用户id不能为空',
                    'numeric' => '用户id为数字'
                ]
            ],
            [
                'field' => 'username',
                'label' => '用户名',
                'rules' => 'required',
                'errors' => [
                    'required' => '用户名不能为空'
                ]
            ],
            [
                'field' => 'nickname',
                'label' => '用户昵称',
                'rules' => 'required',
                'errors' => [
                    'required' => '用户昵称不能为空'
                ]
            ],
            [
                'field' => 'sex',
                'label' => '用户性别',
                'rules' => 'required|numeric',
                'errors' => [
                    'required' => '用户性别不能为空',
                    'numeric' => '用户性别必须为数字'
                ]
            ],
            [
                'field' => 'image',
                'label' => '用户头像',
                'rules' => 'required',
                'errors' => [
                    'required' => '用户头像不能为空'
                ]
            ]
        ];
        $data = $this->input->post();
        $this->form_validation->set_data($data);
        $this->form_validation->set_rules($rules);
        if (!$this->form_validation->run()) {
            $msg = $this->form_validation->error_array();
            $firstErrorMsg = current($msg);
            fail(400, $firstErrorMsg);
        }
        //更新用户信息
        $info = $this->users_model->alertUserInfo($data);
        $info ? success($info) : fail(400, '修改失败!');
    }

    /*
     * 获取账号设置信息
     */
    public function accountSetting()
    {
        $data = $this->input->post();
        if (empty($data['id'])) {
            fail(400, '参数错误!');
        }
        $res = $this->users_model->checkUser($data['id']);
        if (!$res) {
            fail(400, '用户不存在');
        }
        //获取账号信息
        $res = $this->users_model->accountSetting($data['id']);
        success($res);
    }

    /*
     * 获取用户教育信息
     */
    public function EducationInfo()
    {
        $data = $this->input->post();
        if (empty($data['id'])) {
            fail(400, '参数错误!');
        }
        $res = $this->users_model->EducationInfo($data['id']);
        if (!$res) {
            success([]);
        }
        success($res);
    }

    /*
     * 用户教育信息修改/
     */
    public function alertEducationInfo()
    {
        $rules = [
            [
                'field' => 'user_id',
                'label' => '用户id',
                'rules' => 'required|numeric',
                'errors' => [
                    'required' => '用户id不能为空',
                    'numeric' => '用户id必须为数字'
                ]
            ],
            [
                'field' => 'university',
                'label' => '学院名称',
                'rules' => 'required|min_length[4]',
                'errors' => [
                    'required' => '学院名称不能为空',
                    'min_length' => '学院名称长度必须大于4个字符'
                ]
            ],
            [
                'field' => 'major',
                'label' => '专业名称',
                'rules' => 'required|min_length[2]',
                'errors' => [
                    'required' => '专业名称不能为空',
                    'min_length' => '专业名称长度必须大于2个字符'
                ]
            ],

        ];
        $data = $this->input->post();
        $this->form_validation->set_data($data);
        $this->form_validation->set_rules($rules);
        if (!$this->users_model->checkUser($data['user_id'])) {
            fail(400, '用户不存在!');
        }
        if (!$this->form_validation->run()) {
            $data = $this->form_validation->error_array();
            $data = current($data);
            fail(400, $data);
        }
        $res = $this->users_model->alertEducationInfo($data);
        success($res);
    }

    /*
     * 关注/取消关注
     */
    public function follow()
    {
        $rules = [
            [
                'field' => 'user_id',
                'label' => '关注者id',
                'rules' => 'required|numeric',
                'errors' => [
                    'required' => '关注者id不能为空.',
                    'numeric' => '关注者id必须为数字.'
                ]
            ],
            [
                'field' => 'follow_id',
                'label' => '被关注者id',
                'rules' => 'required|numeric',
                'errors' => [
                    'required' => '关注者id不能为空.',
                    'numeric' => '关注者id必须为数字.'
                ]
            ],
            [
                'field' => 'type',
                'label' => '类型',
                'rules' => 'required|in_list[1,2]',
                'errors' => [
                    'required' => '类型不能为空.',
                    'in_list' => 'type只能为1，2'
                ]
            ]
        ];
        $data = $this->input->post();
        $this->form_validation->set_data($data);
        $this->form_validation->set_rules($rules);
        if ($this->form_validation->run() == FALSE) {
            $data = $this->form_validation->error_array();
            $data = current($data);
            fail('400', $data);
        }
        $sta1 = $this->users_model->checkUser($data['user_id']);
        $sta2 = $this->users_model->checkUser($data['follow_id']);
        $res = $this->users_model->is_follow($data);
        //连接redis
        $conn = getRedis();
        $conn->selectDb(0);
        //我的关注集合key
        $key = $data['user_id'] . '_follow';
        $key2 = $data['follow_id'] . '_fans';
        //从缓存中读取我的全部关注列表
        $follows = $conn->zRange($key2, 0, -1);

        if (!$sta1 || !$sta2) {
            fail(400, '该用户不存在!');
        }

        //关注
        if ($data['type'] == 1) {
            if ($res) {
                fail(400, '该用户您已经关注!');
            }
            //关注数据库操作
            unset($data['type']);
            $res2 = $this->users_model->follow($data);
            if (!$res2) {
                fail(400, '操作出错!');
            }
            //关注的redis操作
            if (!empty($follows)) {
                if (in_array($data['user_id'], $follows)) {
                    fail(400, '该用户已经被关注!');
                }
            }
            //添加到我的关注集合
            $res1 = $conn->zAdd($key, [time() => $data['follow_id']]);
            if (!$res1) {
                fail(400, '关注失败!');
            }
            //添加到他的粉丝集合
            $res2 = $conn->zAdd($key2, [time() => $data['user_id']]);
            if (!$res2) {
                fail(400, '关注失败!');
            }
            success($res2, '关注成功!');
        } else {
            //取消关注操作
            unset($data['type']);
            if (!$res) {
                fail(400, '该用户您未关注!');
            }
            $res2 = $this->users_model->unFollow($data);
            if (!$res2) {
                fail(400, '操作出错!');
            }
            //取消关注的redis操作
            if (!empty($follows)) {
                if (!in_array($data['user_id'], $follows)) {
                    fail(400, '该用户您未关注!');
                }
            }
            //从自己的关注列表移除
            $res1 = $conn->zRem($key, [$data['follow_id']]);
            if (!$res1) {
                fail(400, '取消关注失败!');
            }
            //从他的粉丝集合移除
            $res2 = $conn->zRem($key2, [$data['user_id']]);
            if (!$res2) {
                fail(400, '取消关注失败!');
            }
            success($res2, '取消关注成功!');
        }
    }

    /*
     * 获取关注列表
     */
    public function followList()
    {
        $data = $this->input->post();
        if (empty($data['id'])) {
            fail(400, '获取失败!');
        }
        //先从redis中获取关注列表
        $conn = getRedis();
        $conn->selectDb(0);
        $key = $data['id'] . '_follow';
        $key2 = $data['id'] . '_fans';
        $id_array = $conn->zRange($key, 0, -1);
        $fans_array = $conn->zRange($key2, 0, -1);
        //redis中未获取到，在数据库中获取
        if (empty($id_array)) {
            $res1 = $this->users_model->followList($data['id']);
            $id_array = $res1 ? array_column($res1, 'follow_id') : null;
        }
        //没有关注的人
        if ($id_array == null) {
            success(null);
        }
        //根据id查询用户基本信息
        $res = $this->users_model->getUserInfoByIds($id_array);
        //获取该用户是否已经关注了你
        foreach ($res as $k => &$v) {
            if (empty($fans_array)) {
                $res[$k]['status'] = 0;
            } else {
                if (in_array($v['id'], $fans_array)) {
                    //互相关注
                    $res[$k]['status'] = 1;
                } else {
                    //未互相关注
                    $res[$k]['status'] = 0;
                }
            }
        }
        success($res, '获取成功!');
    }

    /*
     * 获取粉丝列表
     */
    public function fansList()
    {
        $data = $this->input->post();
        if (empty($data['id'])) {
            fail(400, '参数错误!');
        }
        $sta = $this->users_model->checkUser($data['id']);
        if (!$sta) {
            fail(400, '该用户不存在!');
        }
        $conn = getRedis();
        $conn->selectDb(0);
        //缓存中获取粉丝列表
        $key = $data['id'] . "_fans";
        $fans_list = $conn->zRange($key, 0, -1);
        //缓存中未获取到
        if (empty($fans_list)) {
            $res = $this->users_model->fansList($data['id']);
            if ($res == null) {
                //没有粉丝
                success(null);
            }
            $fans_list = array_column($res, 'user_id');
            //将该数据写入缓存中
            $res1 = $conn->zAdd($key, $fans_list);
            if (!$res1) {
                fail(400, '操作失败!');
            }
        }
        //通过获取到的粉丝列表id，查询用户的基本信息
        $result = $this->users_model->getUserInfoByIds($fans_list);
        //查看我的粉丝是否关注了我
        $key2 = $data['id'] . '_follow';
        $follow_list = $conn->zRange($key2, 0, -1);
        //缓存中未获取到
        if (empty($follow_list)) {
            $res3 = $this->users_model->followList($data['id']);
            if (empty($res3)) {
                $follow_list = null;
            } else {
                //若数据库中查到
                $follow_list = array_column($res3, 'follow_id');
                if (!empty($follow_list)) {
                    $status = $conn->zAdd($key2, $follow_list);
                    if (!$status) {
                        fail('400', '操作失败!');
                    }
                }
            }
        }
        foreach ($result as $k => &$v) {
            if (empty($follow_list)) {
                $result[$k]['status'] = 0;
            } else {
                in_array($v['id'], $follow_list) ? $result[$k]['status'] = 1 : $result[$k]['status'] = 0;
            }
        }
        $result ? success($result, '获取粉丝列表成功!') : fail(400, '获取粉丝列表失败!');
    }

    /*
     * 用户通过手机号发送短信
     */
    public function bindPhone()
    {
        $conn = getRedis();
        $conn->selectDb(0);
        $data = $this->input->post();
        if (empty($data['id']) || empty($data['phone'])) {
            fail(400, '参数错误!');
        }
        $res1 = validate_phone($data['phone']);
        if (!$res1) {
            fail(400, '手机号码格式错误!');
        }
        $res2 = $this->users_model->existPhone($data['phone']);
        if ($res2) {
            fail(400, '该手机号码已经绑定!');
        }
        $res = $this->users_model->checkUser($data['id']);
        if (!$res) {
            fail(400, '该用户不存在!');
        }
        $key = $data['id'] . "_msg_" . $data['phone'];
        //通过手机号发送短信验证码
        $code = rand_code(4);
        //上锁
        if (!$conn->setNx($key, $code)) {
            fail(400, "您操作的太快了！上个验证码还未过期!");
        }
        //60秒过期
        $conn->expire($key, 60);
        $status = send_msg($data['phone'], $code);
        if (!$status) {
            //发送短信失败!
            //删除缓存
            $conn->del($key);
            fail(400, '短信发送失败!');
        }
        success($code, "发送成功!");
    }

    /*
     * 绑定手机号
     */
    public function bindPhoneSubmit()
    {
        $conn = getRedis();
        $conn->selectDb(0);
        $data = $this->input->post();
        if (empty($data['id']) || empty($data['phone']) || empty($data['code'])) {
            fail(400, '参数错误!');
        }
        $res1 = validate_phone($data['phone']);
        if (!$res1) {
            fail(400, '手机号码格式错误!');
        }
        $res2 = $this->users_model->existPhone($data['phone']);
        if ($res2) {
            fail(400, '该手机号码已经绑定!');
        }
        $res = $this->users_model->checkUser($data['id']);
        if (!$res) {
            fail(400, '该用户不存在!');
        }
        //验证短信验证码是否正确
        $key = $data['id'] . "_msg_" . $data['phone'];
        $code = $conn->get($key);
        if (empty($code)) {
            fail(400, '未发送验证码!');
        }
        if ($code != $data['code']) {
            fail(400, '验证码错误!');
        }
        //执行绑定手机号操作
        $res = $this->users_model->bindPhoneSubmit($data);
        if (!$res) {
            fail(400, '操作失败!');
        }
        //成功将redis中的验证码删除
        $conn->del($key);
        success([], '绑定手机号成功');
    }

    /*
     * 用户签到
     */
    public function signIn()
    {
        $data = $this->input->post();
        $rules = [
            [
                'field' => 'user_id',
                'label' => '用户id',
                'rules' => 'required',
                'errors' => [
                    'require' => '用户id不能为空',
                ]
            ],
        ];
        $res = $this->validate($data, $rules);
        if (!$res) {
            fail(400, '参数错误!');
        }
        $data['init_date'] = date('Y-m-d', time());
        $isSignIn = $this->users_model->isSignIn($data);
        if ($isSignIn) {
            fail(400, '已签到,不可重复签到!');
        }
        //获取当前用户昨天签到的keep_time+1,若没有则为1;
        $time = date('Y-m-d', strtotime('-1 days'));
        $data['keep_time'] = $this->users_model->getSignInKeep($data['user_id'], $time);
        //签到操作
        $data1 = $this->users_model->signIn($data);
        if (!$data1) {
            fail(400, '签到失败!');
        }
        //签到成功增加一个骰子
        $res = $this->Activity_service->addDice($data['user_id'],'signIn');
        if ($res){
            $data['magicBox'] = $res['magicBox'];
        }
        success($data, '签到成功!');
    }

    /*
     * 增加标签
     */
    public function addTag()
    {
        $rules = [
            [
                'field' => 'name',
                'label' => '标签名',
                'rules' => 'required',
                'errors' => [
                    'required' => '标签名不能为空'
                ]
            ],
            [
                'field' => 'user_id',
                'label' => '用户id',
                'rules' => 'required',
                'errors' => [
                    'required' => '用户id不能为空'
                ]
            ]
        ];
        $data = $this->input->post();
        $msg = $this->validate($data, $rules);
        if ($msg !== true) {
            fail(400, $msg);
        }
        $status = $this->users_model->checkUser($data['user_id']);
        if ($status != true) {
            fail(400, '用户id不能为空!');
        }
        $data['create_time'] = time();
        $res = $this->users_model->addTag($data);
        if (!$res) {
            fail(400, '标签新增失败!');
        }
        success($res);
    }

    //用户标签列表
    public function tagList()
    {
        $data = $this->input->post();
        if (empty($data['user_id']) || $this->users_model->checkUser($data['user_id'])) {
            fail(400, '用户id不能为空');
        }
        $res = $this->users_model->tagList($data['user_id']);
        if (!$res) {
            fail(400, '读取失败!');
        }
        success($res);
    }

    // 新增收藏夹
    public function addFavorites()
    {
        $data = $this->input->post();
        if (empty($data['user_id']) || $this->users_model->checkUser($data['user_id'])) {
            fail(400, '用户id不能为空');
        }
        if (empty($data['name'])) {
            fail(400, '收藏夹名不能为空');
        }
        if ($this->users_model->existFavoritesName($data)) {
            fail(400, '收藏夹名已存在');
        }
        $data['create_time'] = time();
        if (!$this->users_model->addFavorites($data)) {
            fail(400, '新增收藏夹失败');
        }
        success();
    }

    // 我的收藏夹
    public function favoritesList()
    {
        $data = $this->input->post();
        if (empty($data['user_id']) || !$this->users_model->checkUser($data['user_id'])) {
            fail(400, '用户id出错');
        }
        $res = $this->users_model->favoritesList($data['user_id']);
        $res1 = $this->users_model->collectionList($data['user_id']);
        $res = array_column($res, null, 'id');
        foreach ($res1 as $k => $v) {
            foreach ($res as $k1 => $v1) {
                if ($v['f_id'] == $k1) {
                    $res[$k1]['data'][$k] = $v;
                }
            }
        }
        if (!$res) {
            success(200, '用户还没有收藏夹');
        }
        success($res);
    }

    //收藏
    public function collection()
    {
        $data = $this->input->post();
        if (empty($data['user_id']) || empty($data['article_id']) || empty($data['f_id'])) {
            fail(400, '参数错误');
        }
        if ($this->users_model->existCollection($data)) {
            fail(400, '您已收藏该文章');
        }
        $data['create_time'] = time();
        $res = $this->users_model->collection($data);
        if (!$res) {
            fail(400, '收藏失败');
        }
        success($res, '收藏成功');
    }

    //修改头像
    public function uploadImage()
    {
        $data = $this->input->post();
        $image = imgUpload();
        $res = $this->users_model->commonUpdate('users', ['image' => $image], ['id' => $data['id']]);
        if (!$res) {
            fail(400, '更新头像失败');
        }
        success(200, '跟新头像成功');
    }

    //获取我的背包道具
    public function rucksack()
    {
        $data = $this->input->post();
        if (empty($data['uid'])){
            fail(400,'用户id不能为空');
        }
       $data =  $this->users_model->myRucksack($data['uid']);
       success($data);
    }
}